from PyQt5.QtCore import Qt, QTimer
from PyQt5.QtGui import QImage, QPixmap
import cv2


class CameraViewer:
    """
    CameraViewer 类用于通过Qt界面显示摄像头捕捉到的图像，并进行人脸识别。

    :param label_qian: 前面的标签对象，用于显示原始摄像头画面。
    :param label_hou: 后面的标签对象，用于显示经过处理（如人脸识别）后的摄像头画面。
    """

    def __init__(self, label_qian, label_hou):
        """
        初始化CameraViewer实例。

        :param label_qian: 前面的标签对象。
        :param label_hou: 后面的标签对象。
        """
        self.label_qian = label_qian
        self.label_hou = label_hou
        # 加载人脸识别的分类器
        self.cascade_classifier = cv2.CascadeClassifier(
            'D:/Programming_Softwares/OpenCV/opencv/sources/data/haarcascades/haarcascade_frontalface_alt2.xml')
        # 初始化摄像头
        self.camera = cv2.VideoCapture(0)

    def open_camera(self):
        """
        打开摄像头，并启动图像捕捉和处理的定时器。
        """
        self.timer = QTimer()
        self.timer.timeout.connect(self.show_camera)
        self.timer.start(30)

    def show_camera(self):
        # 从摄像头读取帧
        ret, frame = self.camera.read()
        if ret:
            # 复制原始帧用于label_qian
            frame_qian = frame.copy()

            # 将帧转换为灰度图像以进行人脸识别（针对label_hou）
            gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

            # 在灰度图像上检测人脸并绘制矩形框（仅针对label_hou）
            faces = self.cascade_classifier.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=5, minSize=(30, 30))
            for (x, y, w, h) in faces:
                cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2)

                # 将带有矩形框的帧转换为QImage以在label_hou中显示
            frame_rgb_hou = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
            height_hou, width_hou, channels_hou = frame_rgb_hou.shape
            bytes_per_line_hou = channels_hou * width_hou
            qt_image_hou = QImage(frame_rgb_hou.data, width_hou, height_hou, bytes_per_line_hou, QImage.Format_RGB888)
            pixmap_hou = QPixmap.fromImage(qt_image_hou)
            self.label_hou.setPixmap(
                pixmap_hou.scaled(self.label_hou.size(), Qt.KeepAspectRatio, Qt.SmoothTransformation)
            )

            # 将原始帧转换为QImage以在label_qian中显示
            frame_rgb_qian = cv2.cvtColor(frame_qian, cv2.COLOR_BGR2RGB)
            height_qian, width_qian, channels_qian = frame_rgb_qian.shape
            bytes_per_line_qian = channels_qian * width_qian
            qt_image_qian = QImage(frame_rgb_qian.data, width_qian, height_qian, bytes_per_line_qian,
                                   QImage.Format_RGB888)
            pixmap_qian = QPixmap.fromImage(qt_image_qian)
            self.label_qian.setPixmap(
                pixmap_qian.scaled(self.label_qian.size(), Qt.KeepAspectRatio, Qt.SmoothTransformation)
            )


    def close_camera(self):
        """
        关闭摄像头，停止图像捕捉定时器。
        """
        self.timer.stop()
        self.camera.release()
